from subprocess import Popen, PIPE
from tempfile import mkstemp
from os import remove
from xml.sax.saxutils import escape

class Executor:
    def __init__(self):
        self.proc = None
        self.path = ''
    
    def createProcessHandle(self, input):
        #create a temporare file that can later be executed
        f, self.path = mkstemp()
        f = file(self.path, 'w')
        f.write(input.get_text())
        f.close()
        
        #open process handle
        self.proc = Popen(['python', '%s'%self.path], stdout=PIPE, stderr=PIPE)
        return self.proc
        
    def execute(self, input):
        #test if proc is usable
        if self.proc and not self.proc.poll() is None:
            self.proc = None
            self.path = ''
            return
        
        #execute the file
        out, err = self.proc.communicate()
        
        # give output back
        if err:
            err = self.parseError(err, input.ancestor.caption, self.path)
        remove(self.path)
            
        input.ancestor.getChildren('Output').set_output(out, err)
        
    def parseError(self, err, inputname, execpath):
        err = err.splitlines()
        err.pop(0)
        type, value = err.pop().split(': ' ,1)
        trace = []
        while err:
            t = err.pop(0)
            path, line, funcname = t.split(', ', 2)
            path = path.replace('File "', '', 1).strip('" \t')
            if path==execpath:
                path = 'Input(name=%s)'%inputname
            line = line.strip(' line\t')
            funcname = funcname.replace('in', '', 1).strip(' \t')
            code = err.pop(0).strip(' \t')
            trace.append([path, line, funcname, code])
            
        trace = "<trace>%s</trace>"%escape(str(trace))
        type = "<type>%s</type>"%escape(str(type))
        value = "<value>%s</value>"%escape(str(value))
        error = "<symbide_error>%s%s%s</symbide_error>"%(trace, type, value)
        return error
        
        
        
    